package com.ssm.mq.service;

import com.rabbitmq.client.Channel;
import com.ssm.mq.config.AmqpConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.messaging.handler.annotation.Headers;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.Map;

@Slf4j
@Service
public class AmqpConsumerMethod {
    @RabbitListener(queues = AmqpConfig.QUEUE_NAME)
    public void receive1(Object message) {
        log.info(AmqpConfig.QUEUE_NAME + ": " + message);
    }

    // @RabbitListener(queues = AmqpConfig.QUEUE_NAME_TTL)
    public void receive2(@Payload String body, @Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag, Message message, Channel channel) {
        log.info(AmqpConfig.QUEUE_NAME_TTL + ": " + body);
        try {
            // multiple 为 false，只确认当前 deliveryTag 对应的消息。为 true，确认当前 deliveryTag 及之前所有未确认的消息
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false); // 手动确认
        } catch (IOException e) {
            try {
                channel.basicNack(message.getMessageProperties().getDeliveryTag(), true, true);
            } catch (IOException ex) {
                log.error("receive2", ex);
            }
        }
    }

    @RabbitListener(queues = AmqpConfig.QUEUE_NAME_DLX)
    public void receive3(@Payload String body, @Headers Map<String, Object> headers, Message message, Channel channel) {
        log.error(AmqpConfig.QUEUE_NAME_DLX + ": " + body);
    }

    @RabbitListener(queues = AmqpConfig.QUEUE_NAME_ANONYMOUS)
    public void receive4(@Payload String body, @Headers Map<String, Object> headers, Message message, Channel channel) {
        log.info(AmqpConfig.QUEUE_NAME_ANONYMOUS + ": " + body);
    }

    // 通过 @RabbitListener 的 bindings 属性声明 Binding（若 RabbitMQ 中不存在该绑定所需要的 Queue、Exchange、RouteKey 则自动创建，若存在则抛出异常）
    @RabbitListener(bindings = @QueueBinding(
        exchange = @Exchange(value = "@RabbitListener", type = ExchangeTypes.TOPIC),
        value = @Queue(value = "@RabbitListener", durable = "true"),
        key = ""
    ))
    public void receive4(Message message) {
        log.info("@RabbitListener" + ": " + message);
    }

    @RabbitListener(queues = AmqpConfig.QUEUE_NAME_ALTERNATE)
    public void receive5(Object message) {
        log.info(AmqpConfig.QUEUE_NAME_ALTERNATE + ": " + message);
    }
}